package com.hilinos.common.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.util.concurrent.locks.ReadWriteLock;

@Slf4j
public class LockUtils {

    public static <T> T doReadLock(ReadWriteLock lock, Runnable<T> runnable) {
        if (ObjectUtils.isEmpty(lock)) {
            return null;
        }
        if (log.isDebugEnabled()) {
            log.debug("加入读锁:{}", lock.hashCode());
        }
        lock.readLock().lock();
        try {
            return runnable.run();
        } catch (Exception e) {
            log.error("执行失败", e);
            return null;
        } finally {
            lock.readLock().unlock();
            if (log.isDebugEnabled()) {
                log.debug("释放读锁:{}", lock.hashCode());
            }
        }

    }

    public static <T> T doWriteLock(ReadWriteLock lock, Runnable<T> runnable) {
        if (ObjectUtils.isEmpty(lock)) {
            return null;
        }
        if (log.isDebugEnabled()) {
            log.debug("加入写锁:{}", lock.hashCode());
        }
        lock.writeLock().lock();
        try {
            return runnable.run();
        } catch (Exception e) {
            log.error("执行失败", e);
        } finally {
            lock.writeLock().unlock();
            if (log.isDebugEnabled()) {
                log.debug("释放写锁:{}", lock.hashCode());
            }
        }
        return null;
    }

    public interface Runnable<T> {
        T run() throws Exception;
    }

}
